/*
 * JniRecordCaster.cpp
 *
 *  Created on: 2018年9月2日
 *      Author: zhengboyuan
 */

#include "JniRecordCaster.h"
#include "CLog.h"
#include "TSingleton.h"


typedef comn::Singleton< JniRecordCaster >		JniRecordCasterSingleton;


JniRecordCaster& JniRecordCaster::instance()
{
	return JniRecordCasterSingleton::instance();
}

JniRecordCaster::JniRecordCaster():
	m_jvm(),
	m_listener()
{

}

JniRecordCaster::~JniRecordCaster()
{
	close();
}

void JniRecordCaster::init()
{
	av::PsRecordCaster::init();

	CLog::setLogger(CLog::COUT);
}

void JniRecordCaster::quit()
{
	av::PsRecordCaster::quit();
}

bool JniRecordCaster::open(const char* dbpath)
{
	getCaster().setEventSink(this);

	return getCaster().open(dbpath);
}

void JniRecordCaster::close()
{
	getCaster().close();
}

bool JniRecordCaster::isOpen()
{
	return (getCaster().isOpen());
}

av::PsRecordCaster& JniRecordCaster::getCaster()
{
	return av::PsRecordCaster::instance();
}

void JniRecordCaster::setJvm(JavaVM* jvm)
{
	m_jvm = jvm;
}

void JniRecordCaster::onCasterEvent(int channel, int event)
{
	CLog::info("JniRecordCaster::onCasterEvent. channel: %d, event: %d\n", channel, event);

	fireCasterEvent(channel, event);
}

void JniRecordCaster::setListener(JNIEnv * env, jobject jlistener)
{
	releaseListener(env);

	if (!jlistener)
	{
		return;
	}

	comn::AutoCritSec lock(m_cs);
	m_listener = env->NewGlobalRef(jlistener);
}

void JniRecordCaster::releaseListener(JNIEnv * env)
{
	comn::AutoCritSec lock(m_cs);

	if (m_listener)
	{
		env->DeleteGlobalRef(m_listener);
		m_listener = NULL;
	}
}

void JniRecordCaster::fireCasterEvent(int channel, int event)
{
	if (!m_listener)
	{
		return;
	}

	JNIEnv* env = NULL;
	m_jvm->AttachCurrentThread(&env, NULL);

	{
		comn::AutoCritSec lock(m_cs);

		jclass cls = env->GetObjectClass(m_listener);
		jmethodID callback = env->GetMethodID(cls, "onCasterEvent", "(II)V");
		if (callback)
		{
			env->CallVoidMethod(m_listener, callback, channel, event);
		}
	}

	m_jvm->DetachCurrentThread();
}
